﻿//
//  Copyright (c) Microsoft Corporation. All rights reserved.
//  Licensed under the MIT License. See License.txt in the project root for license information.
//
namespace Microsoft.VisualStudio.Text.Formatting
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Threading;
    using Microsoft.VisualStudio.Text;

    /// <summary>
    /// Generates text view line from text snapshots.
    /// </summary>
    public interface ITextViewLineSource
    {
        /// <summary>
        /// Gets the top text snapshot for which this source will provide formatted text.
        /// </summary>
        ITextSnapshot TopTextSnapshot { get; }

        /// <summary>
        /// Gets the source text snapshot for which this source will provide formatted text.
        /// </summary>
        ITextSnapshot SourceTextSnapshot { get; }

        /// <summary>
        /// Gets the <see cref="ITextAndAdornmentSequencer"/> used by this source.
        /// </summary>
        ITextAndAdornmentSequencer TextAndAdornmentSequencer { get; }

        /// <summary>
        /// Gets the number of spaces between each tab stop.
        /// </summary>
        int TabSize { get; }

        /// <summary>
        /// Gets the width of a column in pixels.
        /// </summary>
        /// <remarks>This is used to determine the location of tab stops.</remarks>
        double ColumnWidth { get; }

        /// <summary>
        /// Gets the nominal height of a line.
        /// </summary>
        /// <remarks>
        /// This will not, in general, be the same as TextHeightAboveBaseline + TextHeightBelowBaseline since there is might be some padding between
        /// lines.</remarks>
        double LineHeight { get; }

        /// <summary>
        /// Gets the nominal height of the text above the baseline.
        /// </summary>
        double TextHeightAboveBaseline { get; }

        /// <summary>
        /// Gets the nominal height of the text below the baseline.
        /// </summary>
        double TextHeightBelowBaseline { get; }

        /// <summary>
        /// Gets the base indentation (in logical pixels) for all lines generated by this source.
        /// </summary>
        /// <remarks>
        /// This is generally a small value like 2.0, so that some characters (such as an italic slash) will not be clipped
        /// by the left edge of the view.
        /// </remarks>
        double BaseIndentation { get; }

        /// <summary>
        /// Gets the width (in logical pixels) where the formatted text will be broken into multiple lines. 
        /// </summary>
        /// <remarks>The value 0.0 means that lines should never be broken.</remarks>
        double WordWrapWidth { get; }

        /// <summary>
        /// Gets the maximum auto-indent for wrapped lines.
        /// </summary>
        /// <remarks>
        /// If a long line is word-wrapped, then all the line fragments after the first will be indented by 
        /// the amount of leading white space on the first line, or MaxAutoIndent, whichever is smaller.
        /// </remarks>
        double MaxAutoIndent { get; }

        /// <summary>
        /// True if the formatter uses WPF Display TextFormattingMode, false otherwise.
        /// </summary>
        bool UseDisplayMode { get; }

        /// <summary>
        /// Formats the text and adornments in a <see cref="ITextSnapshotLine"/>.
        /// </summary>
        /// <param name="visualLine">The line to format.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> used to indicate when to give up on doing accurate colorization. null indicates that colorization should be done using the inaccurate versions of the
        /// classifier that return results quickly (even if they are inaccurate) and correct any errors once accurate results have been calculated.</param>
        /// <returns>The formatted text for that line.</returns>
        /// <remarks>
        /// <para>
        /// <see cref="ITextViewLine"/> objects are <see cref="IDisposable"/>. The caller must explicitly call Dispose() on the returned lines when they are
        /// done with them.
        /// </para>
        /// <para>
        /// The supplied <see cref="ITextSnapshotLine"/> must belong to the snapshot of the visual buffer, since visuals 
        /// live on that buffer.
        /// </para>
        /// </remarks>
        Collection<ITextViewLine> FormatLineInVisualBuffer(ITextSnapshotLine visualLine, CancellationToken? cancellationToken = null);

        /// <summary>
        /// Formats the text and adornments in a <see cref="ITextSnapshotLine"/> if and only if the text properties have changed.
        /// </summary>
        /// <param name="visualLine">The line to format.</param>
        /// <param name="oldLines">Previously formatted line(s) for <paramref name="visualLine"/>.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/> used to indicate when to give up on doing accurate colorization. null indicates that colorization should be done using the inaccurate versions of the
        /// classifier that return results quickly (even if they are inaccurate) and correct any errors once accurate results have been calculated.</param>
        /// <returns>null if the text properties for <paramref name="visualLine"/> haven't changed; the newly formatted text for that line otherwise.</returns>
        /// <remarks>
        /// <para>
        /// <see cref="ITextViewLine"/> objects are <see cref="IDisposable"/> and must be disposed explicitly.
        /// </para>
        /// <para>
        /// The supplied <see cref="ITextSnapshotLine"/> must belong to the snapshot of the visual buffer, since visuals 
        /// live on that buffer.
        /// </para>
        /// <para>
        /// This method should only be used if you know that there have been no changes to <paramref name="visualLine"/>'s text or space negotiating adornments.
        /// </para>
        /// </remarks>
        Collection<ITextViewLine> FormatLineInVisualBufferIfChanged(ITextSnapshotLine visualLine, IList<ITextViewLine> oldLines, CancellationToken? cancellationToken = null);

    }
}
